package com.devbobcorn.nekoration.blocks;

import java.util.Collections;
import java.util.List;

import com.devbobcorn.nekoration.NekoColors;
import com.devbobcorn.nekoration.blocks.entities.PhonographBlockEntity;
import com.devbobcorn.nekoration.client.ClientHelper;
import com.devbobcorn.nekoration.client.rendering.MusicRenderer;
import com.devbobcorn.nekoration.items.ModItems;
import com.devbobcorn.nekoration.items.PaletteItem;
import com.devbobcorn.nekoration.network.ModPacketHandler;
import com.devbobcorn.nekoration.network.S2CChangeMusic;
import com.devbobcorn.nekoration.network.S2CStartMusic;
import com.devbobcorn.nekoration.utils.TagTypes;
import com.google.gson.Gson;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.loot.LootContext;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.PacketDistributor;

public class PhonographBlock extends Block{
    public PhonographBlock(Properties settings) {
        super(settings);
    }

    @Override
	public boolean hasTileEntity(BlockState state) {
		return true;
	}

	// Called when the block is placed or loaded client side to get the tile entity for the block
	// Should return a new instance of the tile entity for the block
	@Override
	public TileEntity createTileEntity(BlockState state, IBlockReader world) {
		return new PhonographBlockEntity();
	}

    // Called just after the player places a block.
	@Override
	public void setPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
		super.setPlacedBy(worldIn, pos, state, placer, stack);

		TileEntity tileentity = worldIn.getBlockEntity(pos);
		if (tileentity instanceof PhonographBlockEntity) { // prevent a crash if not the right type, or is null
            return;
		}
        LOGGER.error("Tile Entity NOT Found!");
	}

	@Override
	public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
		return Collections.singletonList(new ItemStack(this.asItem()));
	}

	public static class ComponentTag {
		private String text;
	}

	@Override
	public ActionResultType use(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult) {
		ItemStack itemStack = player.getItemInHand(hand);
		Item item = itemStack.getItem();
		PhonographBlockEntity te = (PhonographBlockEntity)world.getBlockEntity(pos);

		boolean flag = player.getItemInHand(Hand.OFF_HAND).getItem() == ModItems.PAW.get();

		if (item == Items.NAME_TAG){
			if (!world.isClientSide()){
				CompoundNBT tag = itemStack.getOrCreateTag();
				if (tag.contains("display", TagTypes.COMPOUND_NBT_ID)){
					CompoundNBT displayTag = tag.getCompound("display");
					if (displayTag.contains("Name", TagTypes.STRING_NBT_ID)){
						try {
							Gson gson=new Gson();
							String tagString = displayTag.getString("Name");
							ComponentTag obj = gson.fromJson(tagString, ComponentTag.class);
							final S2CChangeMusic packet = new S2CChangeMusic(obj.text);
							ModPacketHandler.CHANNEL.send(PacketDistributor.ALL.noArg(), packet);
						} catch (Exception e){
							e.printStackTrace();
						}
					}
				}
			}
		} else if (item == ModItems.PAW_15.get()){
			te.dir = ((byte)((te.dir + 1) % 24));
		} else if (item == ModItems.PAW_90.get()){
			te.dir = ((byte)((te.dir + 6) % 24));
		} else if (item == ModItems.PAW_LEFT.get()){
			te.offset[0]--;
		} else if (item == ModItems.PAW_RIGHT.get()){
			te.offset[0]++;
		} else if (item == ModItems.PAW_UP.get()){
			te.offset[1]++;
		} else if (item == ModItems.PAW_DOWN.get()){
			te.offset[1]--;
		} else if (item == ModItems.PAW_NEAR.get()){
			te.offset[2]++;
		} else if (item == ModItems.PAW_FAR.get()){
			te.offset[2]--;
		} else if (item == ModItems.PAW.get()){
			te.scale = MathHelper.clamp(te.scale + (flag ? 0.1 : -0.1), 0.1, 10.0);
		} else if (item == Items.MELON_SLICE){
			te.type = (te.type + 1) % MusicRenderer.TYPE_COUNT;
		} else if (item == Items.APPLE){
			te.line++;
		} else if (item == Items.SWEET_BERRIES){
			te.line--;
		} else if (item == ModItems.PALETTE.get()){
			// Dye me!
			CompoundNBT nbt = itemStack.getTag();
			if (nbt != null && nbt.contains(PaletteItem.ACTIVE, TagTypes.BYTE_NBT_ID)){
				byte a = nbt.getByte(PaletteItem.ACTIVE);
				int[] c = nbt.getIntArray(PaletteItem.COLORS);
				// So c[a] is the color we need...
				if (flag)
					te.colors[0] = (NekoColors.getRed(c[a]) << 16) + (NekoColors.getGreen(c[a]) << 8) + NekoColors.getBlue(c[a]);
				else te.colors[1] = (NekoColors.getRed(c[a]) << 16) + (NekoColors.getGreen(c[a]) << 8) + NekoColors.getBlue(c[a]);
			} else {
				if (flag)
					te.colors[0] = PaletteItem.DEFAULT_COLOR_SET[0].getRGB() & 0xFFFFFF;
				else te.colors[1] = te.colors[0] = PaletteItem.DEFAULT_COLOR_SET[0].getRGB() & 0xFFFFFF;
			}
		} else if (!world.isClientSide() && !ClientHelper.chosenMusic.equals(ClientHelper.NULL)){
			final S2CStartMusic packet = new S2CStartMusic();
			ModPacketHandler.CHANNEL.send(PacketDistributor.ALL.noArg(), packet);
		}
		return ActionResultType.SUCCESS;
	}
}
